package com.inspur.cloud.service.dataspace;

import com.inspur.cloud.configuration.ApiConfig;
import com.inspur.cloud.dao.dataspace.UserDao;
import com.inspur.cloud.entity.dataspace.UserEntity;
import com.inspur.cloud.entity.dataspace.common.*;
import com.inspur.cloud.entity.dataspace.vo.ShowListBackParam;
import com.inspur.cloud.exception.ApiException;
import com.inspur.cloud.security.AuthorizationHelper;
import com.inspur.cloud.util.TConstants;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 *user的工具类 ：下载keytab；锁定/解锁；列表展示;检查资源
 */
@Service
public class UserUtilService {
    @Autowired
    UserManagerService userManagerService;
    @Autowired
    private KerberosService kerberosService;
    @Autowired
    private ApiConfig apiConfig;
    @Autowired
    private UserDao userDao;
    /**
     * 下载keytab 压缩文件  zip
     * @param userId 目标用户id
     */
    public void downloadZip(Integer userId, HttpServletResponse response) {
        UserEntity userLogin = AuthorizationHelper.getUser();
        if (null == userId) {
            throw new ApiException("输入为空");
        }
        UserEntity userById = userManagerService.findUserById(userId);
        if (null == userById) {
            throw new ApiException("该用户不存在");
        }
        if (!(userLogin.getId().equals(userById.getId()) || userLogin.getId().equals(userById.getParentId()))) {
            throw new ApiException("无权限");
        }
        String zipFileName =String.format("%s%s",userById.getName(),".tar.gz");
        String os = System.getProperty("os.name");
        String zipFilePath = kerberosService.getZipPathByUserName(userById.getName());
        if (os.toLowerCase(Locale.CHINA).startsWith("win")) {
            ClassLoader classLoader = this.getClass().getClassLoader();
            if (classLoader != null) {
                zipFilePath = classLoader.getResource(String.format("%s%s","tempfiles/",zipFileName)).getPath();//获取文件路径
            }
        }
        File file = new File(zipFilePath);
        if (!file.exists()) {
            throw new ApiException("文件不存在");
        }
        try (InputStream inputStream = new FileInputStream(zipFilePath); BufferedInputStream bis = new BufferedInputStream(inputStream);
             OutputStream outputStream = response.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(outputStream)) {
            response.setContentType("application/octet-stream");
            response.addHeader("Content-disposition",
                    "attachment;filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
            int byteRead = 0;
            byte[] buffer1 = new byte[2048];
            while ((byteRead = bis.read(buffer1, 0, 2048)) > 0) {
                bos.write(buffer1, 0, byteRead);
            }
            bos.flush();
        } catch (IOException e) {
            throw new ApiException("数据流读取失败");
        }
    }

    /**
     * 锁定/解锁用户
     * @param  param 锁定/解锁用户传参对象
     * @param  loginUser 当前登录人
     */
    public void lockOrUnlock(UnlockParam param, UserEntity loginUser) {
        UserEntity lockUser = userManagerService.findUserById(param.getUserId());
        if (null == lockUser) {
            throw new ApiException("不存在此用户：" + param.getUserId());
        }
        if (!lockUser.getParentId().equals(loginUser.getId())) {
            throw new ApiException("无操作权限");
        }
        if (param.getType().trim().equals("1")) {
            //解锁
            lockUser.setFailureTimes(0);
        } else {
            lockUser.setFailureTimes(apiConfig.getFailureTimes());
        }
        userManagerService.save(lockUser);
    }

    /**
     * 列表显示
     * @param param 列表显示传参对象
     * @param id  当前登录id
     */
    public PageResult<ShowListBackParam> showList(ShowListParam param, Integer id) {
        //返回给前端的内容 （总条数 总页数 当前页显示内容:ShowListBackParam）
        PageResult<ShowListBackParam> ret = new PageResult<>();
        //前端显示对象ShowListBackParam集合（username userId description）
        List<ShowListBackParam> listBackParams = new ArrayList<>();
        //根据条件从数据库中获取信息
        Page<UserEntity> allUserEntity = getAllUserEntity(param.getPageIndex(), param.getPageSize(), param.getUserName(), id);
        for (UserEntity userEntity : allUserEntity.getContent()) {
            if ("1".equals(param.getIsTenantGetTen()) && userEntity == userManagerService.findByName(param.getUserLoginName())) {
                continue;
            }
            ShowListBackParam showListBackParam = new ShowListBackParam();
            showListBackParam.setUserName(userEntity.getName());
            showListBackParam.setUserId(userEntity.getId());
            showListBackParam.setDescription(userEntity.getDescription());
            if (userEntity.getFailureTimes() >= apiConfig.getFailureTimes()) {
                showListBackParam.setIsLock("1");
            } else {
                showListBackParam.setIsLock("0");
            }
            listBackParams.add(showListBackParam);
        }
        ret.setCount(allUserEntity.getTotalElements());
        ret.setPageTotal(allUserEntity.getTotalPages());
        ret.setPageList(listBackParams);
        return ret;
    }
    /**
     *获取列表
     * @param index 查询第几页
     * @param  size 每页条数
     * @param userNameKey 用户名字关键字 用于模糊查询
     * @param id  当前登录人id
     */
    public Page<UserEntity> getAllUserEntity(Integer index, Integer size, String userNameKey, Integer id) {
        //第几页  每页多少数据 PageReqParam<Integer> param 前端请求信息
        Sort sort = new Sort(Sort.Direction.DESC, "updDate");
        Pageable pageable = PageRequest.of(index - 1, size, sort);
        Specification<UserEntity> specification = (Specification<UserEntity>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            // 第一个userId为CloudServerDao中的字段，第二个userId为参数
            //模糊查询
            if (StringUtils.isNotBlank(userNameKey))
            {
                list.add(criteriaBuilder.like(root.get("name"), String.format("%s%s%s","%",userNameKey,"%")));
            }
            list.add(criteriaBuilder.equal(root.get("parentId"), id));
            query.orderBy();
            return  criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
        };
        return userDao.findAll(specification, pageable);
    }

    /**
     * 创建租户时检查是否有同名资源存在
     */
    public OpEntityResult isResExist(String userName){
        if (null != userManagerService.findHdfsResourceEntityFirstByUrl(String.format("%s%s%s",TConstants.USRPATH,"/",userName))) {
           return OpEntityResult.fail("该账户对应的hdfs资源已经存在，无法创建此账户");
        }
        if (null != userManagerService.findHbaseResourceEntityBySpaceName(userName)) {
            return OpEntityResult.fail("该账户对应的hbase资源已经存在，无法创建此账户");
        }
        if (null != userManagerService.findHiveResourceEntityBySpaceName(userName)) {
            return OpEntityResult.fail("该账户对应的hive资源已经存在，无法创建此账户");
        }
        if (null != userManagerService.findYarnResourceEntityBySpaceName(userName)) {
            return OpEntityResult.fail("该账户对应的yarn资源已经存在，无法创建此账户");
        }
        return  OpEntityResult.of(1,"可以创建");
    }
}
